home *** CD-ROM | disk | FTP | other *** search
- Path: news.th-darmstadt.de!news
- From: Enno Sandner <enno@intellektik.informatik.th-darmstadt.de>
- Newsgroups: comp.lang.c++,comp.sys.mac.programmer.codewarrior,comp.sys.mac.oop
- Subject: Re: Help needed with Runtime Type Info
- Date: Fri, 05 Jan 1996 15:06:33 +0100
- Organization: Fachbereich Informatik, TH Darmstadt
- Message-ID: <30ED3069.15FB7483@intellektik.informatik.th-darmstadt.de>
- References: <pcal-0401962039480001@slip-d8.rdrop.com>
- NNTP-Posting-Host: kitz.intellektik.informatik.th-darmstadt.de
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-Mailer: Mozilla 2.0b4 (X11; I; SunOS 4.1.3 sun4m)
-
- Patrick Calahan wrote:
- >
- > I need a little assistance from a C++ guru.
- >
- > I have an abstract class B from which D,E and F are derived
- >
- > I also have an abstract class O from which P, Q and R are derived.
- >
- > Objects derived from O need to perform specific operations given a
- > pair of pointers to B's. The operation to be performed depends on
- > precisely what kind of B's are given to the O.
- >
- > I thought that by simply overloading member function f in the O's,
- > I could achieve this affect nicely - f(D*,D*), f(D*,E*), f(E*,F*)...
- > could be defined to handle the particualr pair-cases appropriately.
- > A member function in O f(B*,B*) would handle all cases not handled
- > specifically by the subclasses.
- >
- > The only problem is figuring out exactly what type of object a B* is
- > pointing to so that the appropriate call to O.f can be made. I.e.,
- > given a pointer to a B, I need to cast it to a D*,E*, or F*.
- >
- > On page 640 of Stroustrup, he says that [in dynamic_cast<t>(v)]
- > "If T is void* then v must be a pointer, and the result value is a
- > pointer to the complete object pointed to by v."
- >
- > So, if I read him correctly,
- >
- > dynamic_cast<void*>(p*)
- >
- > should cast p to a pointer to an object of the most complete type of
- > the object pointed to by p, i.e. cast my B* to an D*, E* or F*.
- > This sounds like what I want.
- >
- > Unfortunately, if I try to compile the following using MetroWerks
- > CodeWarrior 7 (I do have RTTI enabled):
- >
- >
- > some_function(B* b1, B*b2, O* o)
- > {
- >
- > // here I need to figure out what types of objects b1 & b2 really are
- > // and cast the pointers so the correct version of f will be called.
- >
- > o->f( dynamic_cast<void*>(b1), dynamic_cast<void*>(b2) );
- >
- > }
- >
- >
- > b1 and b2 apparently get cast to void*; the compiler returns that
- > f(void*,void*) can't be found.
- >
- > What do I need to do here?
- >
- >
- > I'm relatively new to C++, so I might just be looking at the problem
- > incorrectly.
- >
- > I tried to do it just using virtual functions in B, but the fact that
- > I'm dealing with pairs of B's in the O's seems to make this less
- > elegant.
- >
- > Moreover, it makes more sense in my application for O to be a separate
- > class.
- >
- > Many many thanks in advance for any help,
-
- Overloaded functions are selected according to the static type of the
- arguments. This allows to resolve such calls at compile-time.
- Because void-pointers aren't silently converted to any other type the
- compiler looks for a function 'O :: f(void*,void*)' which doesn't
- exists.
- To use the 'dynamic_cast' you need to narrow the pointers to the desired
- type. For example to narrow a B-pointer to a D-pointer you could write:
-
- void f(B* b) { D* d=dynamic_cast<D*>(b); }
-
- If 'b' isn't of type D (or a subclass of D) 'd' will become zero,
- otherwise
- 'd' will point to the appropriate D-object. However this solution will
- lead
- to some code like 'hardcode the possible type and verify the result at
- run-time' (ie. sth. similar to a switch-construct). This should clarify
- that
- the dynamic-cast will not be very useful to solve your problem.
- What you really need is some sort of double-dispatching. You could for
- example build up a map where the elements are functor-objects and the
- keys
- are pairs of typeid's. In this way you can maintain arbitary behavior
- connected
- to a pair of typeid's. This solution can easily be extended to more then
- two
- arguments.
-
- Enno
-